package com.ymatou.iapi.settlement.testcase;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import com.ymatou.i.accounting.api.parameter.AccountBean;
import com.ymatou.iapi.settlement.parameter.AdRateInfoPo;
import com.ymatou.iapi.settlement.parameter.AdRateProductInfo;
import com.ymatou.iapi.settlement.parameter.GenerateAdRateInfoReq;
import com.ymatou.iapi.settlement.parameter.SettleAdCostReq;
import com.ymatou.iapi.settlement.parameter.SettlementDetailPo;
import com.ymatou.iapi.settlement.service.GenerateAdRateInfoCall;
import com.ymatou.iapi.settlement.service.SettleAdCostCall;
import com.ymatou.iapi.settlement.service.SettlementService;
import com.ymatou.iapi.trading.operate.parameter.Order;
import com.ymatou.iapi.trading.operate.parameter.OrderInfoPo;
import com.ymatou.iapi.trading.operate.parameter.OrderItemVo;
import com.ymatou.iapi.trading.operate.parameter.PlaceOrderResp;
import com.ymatou.iapi.trading.operate.parameter.PlaceOrderService;
import com.ymatou.iapi.trading.operate.parameter.req.PlaceOrderReq;
import com.ymt.core.tool.Logger;
import com.ymt.utils.annotation.TestCase;
import com.ymt.utils.annotation.TestSuite;
import com.ymt.utils.tag.P1;
import com.ymttest.business.service.OrderCallService;
import com.ymttest.common.enums.CancelOrderTypeEnum;
import com.ymttest.database.model.YmtSettlementInvoice;
import com.ymttest.database.sqlwapper.DefaultWapper;
import com.ymttest.database.sqlwapper.YmtSettlementInvoiceWapper;
import com.ymttest.utils.DataUtil;
import com.ymttest.utils.EnvSetup;
import com.ymttest.utils.TestDataManager;

/**
 * 广告费率结算接口 FreeMaker Template自动生成代码
 */
@TestSuite
public class Ts_SettleAdCost {
	private static SettleAdCostReq settleAdCostReq;
	private static SettleAdCostCall settleAdCostCall;
	private static Map<Integer, AccountBean> mapAccount;
	private static int sellerId = Integer.valueOf(EnvSetup.getData("BuyerId"));
	private static YmtSettlementInvoiceWapper ymtSettlementInvoiceWapper = new YmtSettlementInvoiceWapper();

	@BeforeClass
	public static void setUp() {
		Logger.createResultFile("广告费率结算接口");
	}

	@Before
	public void caseUp() {
		settleAdCostReq = new SettleAdCostReq();
		settleAdCostCall = new SettleAdCostCall();

	}
	@AfterClass
	public static void tearDown() {
		Logger.generateResult(settleAdCostCall.getOpurl());
	}

	@After
	public void caseDown() {
		Logger.end();
	}
	/**
	 * 
	 * 根据商品productid 下单,一个订单下面2个商品，其中一个商品指定produnctid
	 * 
	 */
	private static PlaceOrderResp placeOrder(List<String> proIds) {

		PlaceOrderReq placeorderBean = PlaceOrderService.getDefaultOrderReq();

		OrderItemVo orderitem2 = PlaceOrderService.getDefaultOrderItemVo();

		placeorderBean.getOrderGroups().get(0).getOrders().get(0)
				.getOrderItems().add(orderitem2);

		List<OrderItemVo> orderItemList = placeorderBean.getOrderGroups()
				.get(0).getOrders().get(0).getOrderItems();

		if (!CollectionUtils.isEmpty(proIds)) {

			for (int i = 0; i < orderItemList.size(); i++) {

				if (proIds.size() > i) {

					orderItemList.get(i).setProductId(proIds.get(i));

				}
			}

		}

		return PlaceOrderService.callPlaceOrderService(placeorderBean);

	}
	/**
	 * 订单下所有商品都收取广告费
	 * @param orderId
	 * @param orderInfoList
	 */
	private void callGenerateAdRateInfo(int orderId,
			List<OrderInfoPo> orderInfoList) {

		GenerateAdRateInfoReq generateAdRateInfoReq = new GenerateAdRateInfoReq();
		GenerateAdRateInfoCall generateAdRateInfoCall = new GenerateAdRateInfoCall();

		List<AdRateProductInfo> list = new ArrayList<AdRateProductInfo>();

		orderInfoList
				.forEach(orderInfo -> {

					BigDecimal adCostMax = new BigDecimal(1 + new Random()
							.nextInt(30));

					AdRateProductInfo adRateProductInfo = new AdRateProductInfo();

					adRateProductInfo.setProductId(orderInfo.getProductId());

					adRateProductInfo.setAdId(TestDataManager
							.getRandomIntNum(9));

					adRateProductInfo.setAdCostId(TestDataManager
							.getRandomUUID().toString());

					adRateProductInfo.setAdRate(new BigDecimal(new Random()
							.nextFloat() / 10));

					adRateProductInfo.setAdCostMax(adCostMax);

					list.add(adRateProductInfo);

				});

		generateAdRateInfoReq.setOrderId(orderId);

		generateAdRateInfoReq.setAdProductInfos(list);

		generateAdRateInfoCall.setData(false, generateAdRateInfoReq);

		try {
			generateAdRateInfoCall.callService();

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	private void verifyDd(List<AdRateInfoPo> adRateInfoPoList,
			BigDecimal costAmount) {
		try {

			Thread.sleep(15000);

			long orderId = settleAdCostReq.getOrderId();

			//广告费结算表
			YmtSettlementInvoice ymtSettlementInvoice = ymtSettlementInvoiceWapper
					.selectYmtSettlementInvoice(String.valueOf(orderId)).get(0);

			//校验广告结算表
			verifySettlementInvoice(ymtSettlementInvoice, orderId, costAmount,
					1);

			String invoiceId = ymtSettlementInvoice.getInvoiceId();

			Logger.comment(String.format(
					"校验结算单号:%s 广告费用结算明细表 Ymt_SettlementDetail", invoiceId));

			List<SettlementDetailPo> settlementDetailPoList = ymtSettlementInvoiceWapper
					.selectYmtSettlementDetail(invoiceId);

			//买手奖金池账户
			AccountBean reward = mapAccount.get(14);

			//买手广告费账户
			AccountBean fee = mapAccount.get(13);
			AccountBean rmb = mapAccount.get(1);

			BigDecimal amountReward = reward.getAvailAmount();
			BigDecimal amountFee = fee.getAvailAmount();
			BigDecimal amountRmb = rmb.getAvailAmount();

			Boolean result = DataUtil.isBiggerThan(amountReward.add(amountFee),
					costAmount);

			List<SettlementDetailPo> feeDetailList = settlementDetailPoList
					.stream().filter(detail -> detail.getAccountType() == 13)
					.collect(Collectors.toList());

			List<SettlementDetailPo> rewardDetailList = settlementDetailPoList
					.stream().filter(detail -> detail.getAccountType() == 14)
					.collect(Collectors.toList());
			List<SettlementDetailPo> rmbDetailList = settlementDetailPoList
					.stream().filter(detail -> detail.getAccountType() == 1)
					.collect(Collectors.toList());

			SettlementDetailPo feeDetail = null, rewardDetail = null, rmbDetail = null;

			if (!CollectionUtils.isEmpty(feeDetailList))
				feeDetail = feeDetailList.get(0);
			if (!CollectionUtils.isEmpty(rewardDetailList))
				rewardDetail = rewardDetailList.get(0);
			if (!CollectionUtils.isEmpty(rmbDetailList))
				rmbDetail = rmbDetailList.get(0);

			BigDecimal rewardAmount = BigDecimal.ZERO;
			BigDecimal feeAmount = BigDecimal.ZERO;
			BigDecimal rmbAmount = BigDecimal.ZERO;

			BigDecimal actualTotalCoat = settlementDetailPoList.stream()
					.map(detail -> detail.getAmount())
					.reduce(BigDecimal.ZERO, BigDecimal::add);

			DataUtil.verifyDecimalEquals(actualTotalCoat, costAmount,
					"校验Ymt_SettlementDetail总广告费用结算等于实际需要结算费用");

			//A 13 B 14 
			//A+B>S
			if (Boolean.TRUE == result) {

				Logger.comment("账户扣减方式为A 13+B 14>S");

				feeAmount = costAmount.multiply(amountFee).divide(
						amountFee.add(amountReward), 2,
						BigDecimal.ROUND_HALF_UP);

				rewardAmount = costAmount.subtract(feeAmount);

			}
			//A+B=S
			else if (null == result) {
				Logger.comment("账户扣减方式为A 13+B 14=S");

				feeAmount = feeAmount;
				rewardAmount = amountReward;

			}
			//A+B<S
			else {

				rmbAmount = costAmount.subtract(amountReward).subtract(
						amountFee);

				feeAmount = amountFee;

				rewardAmount = amountReward;

				if (rmbDetail != null) {

					Logger.comment("账户扣减方式为A 13+B 14<S");

					Logger.comment("校验账户类型为1广告费用扣减明细");

					Logger.verifyEquals(invoiceId, rmbDetail.getInvoiceId(),
							"校验InvoiceId");

					Logger.verifyEquals(Long.valueOf(sellerId),
							rmbDetail.getUserId(), "校验UserId");
					Logger.verifyEquals(1, rmbDetail.getAccountType(),
							"校验AccountType");
					Logger.verifyEquals(300035, rmbDetail.getBizCode(),
							"校验BizCode");

					DataUtil.verifyDecimalEquals(rmbAmount,
							rmbDetail.getAmount(), "校验Amount");

					DataUtil.verifyDecimalEquals(amountRmb,
							rmbDetail.getAvailAmount(), "校验AvailAmount");

					Logger.verifyEquals((byte) 1, rmbDetail.getStatus(),
							"校验Status");

				}
			}
			if (rewardDetail != null) {

				Logger.comment("校验账户类型为14广告费用扣减明细");
				Logger.verifyEquals(invoiceId, rewardDetail.getInvoiceId(),
						"校验InvoiceId");
				Logger.verifyEquals(Long.valueOf(sellerId),
						rewardDetail.getUserId(), "校验UserId");
				Logger.verifyEquals(14, rewardDetail.getAccountType(),
						"校验AccountType");
				Logger.verifyEquals(300035, rewardDetail.getBizCode(),
						"校验BizCode");

				DataUtil.verifyDecimalEquals(rewardAmount,
						rewardDetail.getAmount(), "校验Amount");

				DataUtil.verifyDecimalEquals(amountReward,
						rewardDetail.getAvailAmount(), "校验AvailAmount");

				Logger.verifyEquals((byte) 1, rewardDetail.getStatus(),
						"校验Status");

				if (feeDetail != null) {

					Logger.comment("校验账户类型为13广告费用扣减明细");
					Logger.verifyEquals(invoiceId, feeDetail.getInvoiceId(),
							"校验InvoiceId");
					Logger.verifyEquals(Long.valueOf(sellerId),
							feeDetail.getUserId(), "校验UserId");

					Logger.verifyEquals(13, feeDetail.getAccountType(),
							"校验AccountType");
					Logger.verifyEquals(300035, feeDetail.getBizCode(),
							"校验BizCode");

					DataUtil.verifyDecimalEquals(feeAmount,
							feeDetail.getAmount(), "校验Amount");
					DataUtil.verifyDecimalEquals(amountFee,
							feeDetail.getAvailAmount(), "校验AvailAmount");

					Logger.verifyEquals((byte) 1, feeDetail.getStatus(),
							"校验Status");
				}

			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			Logger.fail(e);
		}

	}

	private void verifyDb2(int userId, int sellerId, int orderId,
			List<String> proList) {

		List<Map> list;

		try {

			Thread.sleep(3000);

			list = new DefaultWapper().selectOrderByOderId(orderId);

			List<AdRateInfoPo> adRateInfoPoList = new YmtSettlementInvoiceWapper()

			.selectYmtAdRateInfo(orderId);

			Logger.comment(String.format("校验订单 %s,Ymt_AdRateInfo ", orderId));

			adRateInfoPoList.forEach(ad -> {

				if ((Integer) list.get(0).get("iTradingStatus") == 12) {

					Logger.comment(String.format("Ymt_AdRateInfo productId:"
							+ " %s ", ad.getProductId()));

					Logger.verifyEquals(Long.valueOf(orderId),
							ad.getRelatedCancelId(),
							"校验Ymt_AdRateInfo RelatedCancelId");

				} else {
					Logger.verifyEquals(null, ad.getRelatedCancelId(),
							"校验Ymt_AdRateInfo RelatedCancelId");
				}

			});

			Map map = new HashMap();

			map.put("orderId", orderId);
			map.put("businessType", 13);

			List<YmtSettlementInvoice> ymtSettlementInvoiceList = new YmtSettlementInvoiceWapper()
					.selectYmtSettlementInvoice(map);

			BigDecimal expectSettlementAmount = adRateInfoPoList.stream()
					.filter(ad -> ad.getRelatedCancelId() == null)
					.map(ad -> ad.getCostAmount())
					.reduce(BigDecimal.ZERO, BigDecimal::add);

			DataUtil.verifyDecimalEquals(expectSettlementAmount,
					ymtSettlementInvoiceList.get(0).getCashAmount(),
					"校验实际结算的广告费用");

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
	private void verifySettlementInvoice(
			YmtSettlementInvoice ymtSettlementInvoice, long orderId,
			BigDecimal costAmount, int settlementStatus) {

		Logger.comment(String.format("校验订单号:%s 结算表 Ymt_SettlementInvoice",
				orderId));

		Logger.verifyEquals(orderId,
				Long.valueOf(ymtSettlementInvoice.getOrderId()), "校验OrderId");

		Logger.verifyEquals(13, ymtSettlementInvoice.getBusinessType(),
				"校验BusinessType");

		DataUtil.verifyDecimalEquals(costAmount,
				ymtSettlementInvoice.getTotalAmount(), "校验totalAmount");

		Logger.verifyEquals(sellerId, ymtSettlementInvoice.getSellerId(),
				"校验sellerid");

		Logger.verifyEquals(2, ymtSettlementInvoice.getSettlementUser(),
				"校验SettlementUser");

		Logger.verifyEquals(settlementStatus,
				ymtSettlementInvoice.getSettlementStatus(),
				"校验SettlementStatus");

		Logger.verifyEquals("扣除精准营销费", ymtSettlementInvoice.getRemark(),
				"校验Remark");

	}

	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SettleAdCost_001() {
		Logger.start(true, "买手(广告费用余额+广告费奖金余额)>广告费用,商品结算成功");
		try {

			PlaceOrderResp placeOrderResp = SettlementService
					.placeOrder(sellerId);

			BigDecimal payAmount = placeOrderResp.getPayAmount();

			BigDecimal adRate = BigDecimal.valueOf(0.05);

			//所有广告商品 总的需要结算的费用
			BigDecimal costAmount = payAmount.multiply(adRate);

			//重置广告费用账户 
			SettlementService.resetBuyerAdvertisingFeeAccount(sellerId,
					BigDecimal.ONE);

			//重置广告奖金账户 
			SettlementService.resetBuyerRewardAccount(sellerId,
					costAmount.add(BigDecimal.TEN));

			mapAccount = SettlementService.getAccountByUserId(sellerId);

			List<AdRateInfoPo> adRateInfoPoList = SettlementService
					.generateAdRateInfo(placeOrderResp, adRate);

			long orderId = adRateInfoPoList.get(0).getOrderId();

			Ts_CheckAdCost.callCheckAdCost();

			settleAdCostReq.setOrderId(orderId);

			settleAdCostCall.setData(settleAdCostReq);

			settleAdCostCall.callService();

			Logger.verifyEquals("ok", settleAdCostCall.getReturnData(),
					"校验接口返回");

			verifyDd(adRateInfoPoList, costAmount);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SettleAdCost_002() {
		Logger.start(true, "买手(广告费用余额+广告费奖金余额)=广告费用,商品结算成功");
		try {

			PlaceOrderResp placeOrderResp = SettlementService
					.placeOrder(sellerId);

			BigDecimal payAmount = placeOrderResp.getPayAmount();

			BigDecimal adRate = BigDecimal.valueOf(0.05);

			//所有广告商品 总的需要结算的费用
			BigDecimal costAmount = payAmount.multiply(adRate);

			//重置广告费用账户 
			SettlementService.resetBuyerAdvertisingFeeAccount(sellerId,
					BigDecimal.ONE);
			//重置广告奖金账户 
			SettlementService.resetBuyerRewardAccount(sellerId,
					costAmount.subtract(new BigDecimal(1)));

			mapAccount = SettlementService.getAccountByUserId(sellerId);

			List<AdRateInfoPo> adRateInfoPoList = SettlementService
					.generateAdRateInfo(placeOrderResp, adRate);

			long orderId = adRateInfoPoList.get(0).getOrderId();

			Ts_CheckAdCost.callCheckAdCost();

			settleAdCostReq.setOrderId(orderId);

			settleAdCostCall.setData(settleAdCostReq);

			settleAdCostCall.callService();

			Logger.verifyEquals("ok", settleAdCostCall.getReturnData(),
					"校验接口返回");

			verifyDd(adRateInfoPoList, costAmount);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SettleAdCost_003() {
		Logger.start(true, "买手(广告费用余额+广告费奖金余额)<广告费用,商品结算成功");
		try {
			PlaceOrderResp placeOrderResp = SettlementService
					.placeOrder(sellerId);

			BigDecimal payAmount = placeOrderResp.getPayAmount();

			BigDecimal adRate = BigDecimal.valueOf(0.05);

			//所有广告商品 总的需要结算的费用
			BigDecimal costAmount = payAmount.multiply(adRate);

			//重置广告费用账户 
			SettlementService.resetBuyerAdvertisingFeeAccount(sellerId,
					BigDecimal.ONE);
			//重置广告奖金账户 
			SettlementService.resetBuyerRewardAccount(sellerId,
					costAmount.subtract(new BigDecimal(2)));

			mapAccount = SettlementService.getAccountByUserId(sellerId);

			List<AdRateInfoPo> adRateInfoPoList = SettlementService
					.generateAdRateInfo(placeOrderResp, adRate);

			long orderId = adRateInfoPoList.get(0).getOrderId();

			Ts_CheckAdCost.callCheckAdCost();

			settleAdCostReq.setOrderId(orderId);

			settleAdCostCall.setData(settleAdCostReq);

			settleAdCostCall.callService();

			Logger.verifyEquals("ok", settleAdCostCall.getReturnData(),
					"校验接口返回");

			verifyDd(adRateInfoPoList, costAmount);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SettleAdCost_004() {
		Logger.start(true, "买手(广告费用余额+广告费奖金余额+账户余额)<广告费用,商品结算失败");
		try {

			PlaceOrderResp placeOrderResp = SettlementService
					.placeOrder(sellerId);

			BigDecimal payAmount = placeOrderResp.getPayAmount();

			BigDecimal adRate = BigDecimal.valueOf(0.05);

			//所有广告商品 总的需要结算的费用
			BigDecimal costAmount = payAmount.multiply(adRate);

			//重置广告费用账户 
			SettlementService.resetBuyerAdvertisingFeeAccount(sellerId,
					BigDecimal.ONE);
			//重置广告奖金账户 
			SettlementService.resetBuyerRewardAccount(sellerId, new BigDecimal(
					2));
			//重置余额奖金账户 
			SettlementService.resetRmbAccount(sellerId,
					costAmount.subtract(new BigDecimal(4)));

			mapAccount = SettlementService.getAccountByUserId(sellerId);

			List<AdRateInfoPo> adRateInfoPoList = SettlementService
					.generateAdRateInfo(placeOrderResp, adRate);

			long orderId = adRateInfoPoList.get(0).getOrderId();

			Ts_CheckAdCost.callCheckAdCost();

			settleAdCostReq.setOrderId(orderId);

			settleAdCostCall.setData(settleAdCostReq);

			settleAdCostCall.callService();

			Logger.verifyEquals("fail", settleAdCostCall.getReturnData(),
					"校验接口返回");

			//广告费结算表
			YmtSettlementInvoice ymtSettlementInvoice = ymtSettlementInvoiceWapper
					.selectYmtSettlementInvoice(String.valueOf(orderId)).get(0);

			//校验广告结算表
			verifySettlementInvoice(ymtSettlementInvoice, orderId, costAmount,
					2);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SettleAdCost_005() {
		Logger.start(true, "重复结算广告费");
		try {

			List<AdRateInfoPo> adRateInfoPoList = SettlementService
					.generateAdRateInfo(sellerId, true);

			long orderId = adRateInfoPoList.get(0).getOrderId();

			//所有广告商品 总的需要结算的费用
			BigDecimal costAmount = adRateInfoPoList.stream()
					.map(ad -> ad.getCostAmount())
					.reduce(BigDecimal.ZERO, BigDecimal::add);

			//重置广告费用账户 
			SettlementService.resetBuyerAdvertisingFeeAccount(sellerId,
					new BigDecimal(100));
			//重置广告奖金账户 
			SettlementService.resetBuyerRewardAccount(sellerId, new BigDecimal(
					100));

			//重置余额奖金账户 
			SettlementService
					.resetRmbAccount(sellerId, new BigDecimal(1000000));

			mapAccount = SettlementService.getAccountByUserId(sellerId);

			Ts_CheckAdCost.callCheckAdCost();

			settleAdCostReq.setOrderId(orderId);

			settleAdCostCall.setData(settleAdCostReq);

			settleAdCostCall.callService();

			Thread.sleep(10000);

			settleAdCostCall.callService();

			Logger.verifyEquals("ok", settleAdCostCall.getReturnData(),
					"校验接口返回");

			verifyDd(adRateInfoPoList, costAmount);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SettleAdCost_006() {
		Logger.start(true, "上一次(广告费用余额+广告费奖金余额+账户余额)<广告费,结算失败,充值账户余额后，结算成功");
		try {

			long orderId = SettlementService.settleAdCostFail();

			List<AdRateInfoPo> adRateInfoPoList = new YmtSettlementInvoiceWapper()

			.selectYmtAdRateInfo(orderId);

			//所有广告商品 总的需要结算的费用
			BigDecimal costAmount = adRateInfoPoList.stream()
					.map(ad -> ad.getCostAmount())
					.reduce(BigDecimal.ZERO, BigDecimal::add);

			//重置余额账户 
			SettlementService
					.resetRmbAccount(sellerId, new BigDecimal(1000000));

			mapAccount = SettlementService.getAccountByUserId(sellerId);

			Ts_CheckAdCost.callCheckAdCost();

			settleAdCostReq.setOrderId(orderId);

			settleAdCostCall.setData(settleAdCostReq);

			settleAdCostCall.callService();

			Logger.verifyEquals("ok", settleAdCostCall.getReturnData(),
					"校验接口返回");

			Thread.sleep(10000);

			verifyDd(adRateInfoPoList, costAmount);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SettleAdCost_007() {
		Logger.start(true, "上一次(广告费用余额+广告费奖金余额+账户余额)<广告费,结算失败,充值广告费用余额后，结算成功");
		try {

			long orderId = SettlementService.settleAdCostFail();

			List<AdRateInfoPo> adRateInfoPoList = new YmtSettlementInvoiceWapper()

			.selectYmtAdRateInfo(orderId);

			//所有广告商品 总的需要结算的费用
			BigDecimal costAmount = adRateInfoPoList.stream()
					.map(ad -> ad.getCostAmount())
					.reduce(BigDecimal.ZERO, BigDecimal::add);

			//重置广告账户 余额
			SettlementService.resetBuyerAdvertisingFeeAccount(sellerId,
					new BigDecimal(1000000));

			mapAccount = SettlementService.getAccountByUserId(sellerId);

			Ts_CheckAdCost.callCheckAdCost();

			settleAdCostReq.setOrderId(orderId);

			settleAdCostCall.setData(settleAdCostReq);

			settleAdCostCall.callService();

			Logger.verifyEquals("ok", settleAdCostCall.getReturnData(),
					"校验接口返回");
			Thread.sleep(10000);

			verifyDd(adRateInfoPoList, costAmount);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SettleAdCost_008() {
		Logger.start(true, "上一次(广告费用余额+广告费奖金余额+账户余额)<广告费,结算失败,充值广告奖金账户后，结算成功");
		try {

			long orderId = SettlementService.settleAdCostFail();

			List<AdRateInfoPo> adRateInfoPoList = new YmtSettlementInvoiceWapper()

			.selectYmtAdRateInfo(orderId);

			//所有广告商品 总的需要结算的费用
			BigDecimal costAmount = adRateInfoPoList.stream()
					.map(ad -> ad.getCostAmount())
					.reduce(BigDecimal.ZERO, BigDecimal::add);

			//重置奖金
			SettlementService.resetBuyerRewardAccount(sellerId, new BigDecimal(
					1000000));

			mapAccount = SettlementService.getAccountByUserId(sellerId);

			Ts_CheckAdCost.callCheckAdCost();

			settleAdCostReq.setOrderId(orderId);

			settleAdCostCall.setData(settleAdCostReq);

			settleAdCostCall.callService();

			Logger.verifyEquals("ok", settleAdCostCall.getReturnData(),
					"校验接口返回");

			Thread.sleep(10000);

			verifyDd(adRateInfoPoList, costAmount);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SettleAdCost_009() {
		Logger.start(true, "订单号不存在");
		try {

			long orderId = 11111L;

			settleAdCostReq.setOrderId(orderId);

			settleAdCostCall.setData(settleAdCostReq);

			settleAdCostCall.callService();

			Logger.verifyEquals("ok", settleAdCostCall.getReturnData(),
					"校验接口返回");

			//verifyDd(adRateInfoPoList, costAmount);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SettleAdCost_010() {
		Logger.start(true, "订单号为空");
		try {

			long orderId = 0l;

			settleAdCostReq.setOrderId(orderId);

			settleAdCostCall.setData(settleAdCostReq);

			settleAdCostCall.callService();

			Logger.verifyEquals("ok", settleAdCostCall.getReturnData(),
					"校验接口返回");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({P1.class})
	@TestCase
	@Ignore
	public void Tc_SettleAdCost_011() {
		Logger.start(true, "买手的广告费用账户不存在,结算失败");
		try {

			mapAccount = SettlementService.getAccountByUserId(sellerId);

			List<AdRateInfoPo> adRateInfoPoList = SettlementService
					.generateAdRateInfo(sellerId, true);

			//所有广告商品 总的需要结算的费用
			BigDecimal costAmount = adRateInfoPoList.stream()
					.map(ad -> ad.getCostAmount())
					.reduce(BigDecimal.ZERO, BigDecimal::add);

			long orderId = adRateInfoPoList.get(0).getOrderId();

			Ts_CheckAdCost.callCheckAdCost();

			settleAdCostReq.setOrderId(orderId);

			settleAdCostCall.setData(settleAdCostReq);

			settleAdCostCall.callService();

			Logger.verifyEquals("ok", settleAdCostCall.getReturnData(),
					"校验接口返回");

			verifyDd(adRateInfoPoList, costAmount);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({P1.class})
	@TestCase
	@Ignore
	public void Tc_SettleAdCost_012() {
		Logger.start(true, "买手的广告费用资金账户不存在,结算失败");
		try {

			mapAccount = SettlementService.getAccountByUserId(sellerId);

			List<AdRateInfoPo> adRateInfoPoList = SettlementService
					.generateAdRateInfo(sellerId, true);

			//所有广告商品 总的需要结算的费用
			BigDecimal costAmount = adRateInfoPoList.stream()
					.map(ad -> ad.getCostAmount())
					.reduce(BigDecimal.ZERO, BigDecimal::add);

			long orderId = adRateInfoPoList.get(0).getOrderId();

			Ts_CheckAdCost.callCheckAdCost();

			settleAdCostReq.setOrderId(orderId);

			settleAdCostCall.setData(settleAdCostReq);

			settleAdCostCall.callService();

			Logger.verifyEquals("ok", settleAdCostCall.getReturnData(),
					"校验接口返回");

			verifyDd(adRateInfoPoList, costAmount);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SettleAdCost_013() {
		Logger.start(true, "买手(广告费用余额+广告费奖金余额)>广告费用,"
				+ "广告费用余额或广告费奖金余额为0，商品广告费用结算成功");
		try {

			List<AdRateInfoPo> adRateInfoPoList = SettlementService
					.generateAdRateInfo(sellerId, true);

			//所有广告商品 总的需要结算的费用
			BigDecimal costAmount = adRateInfoPoList.stream()
					.map(ad -> ad.getCostAmount())
					.reduce(BigDecimal.ZERO, BigDecimal::add);

			//重置广告费用账户 
			SettlementService.resetBuyerAdvertisingFeeAccount(sellerId,
					BigDecimal.ZERO);
			//重置广告费用账户 
			SettlementService.resetBuyerRewardAccount(sellerId,
					BigDecimal.TEN.add(costAmount));

			Ts_CheckAdCost.callCheckAdCost();

			long orderId = adRateInfoPoList.get(0).getOrderId();

			mapAccount = SettlementService.getAccountByUserId(sellerId);

			settleAdCostReq.setOrderId(orderId);

			settleAdCostCall.setData(settleAdCostReq);

			settleAdCostCall.callService();

			Logger.verifyEquals("ok", settleAdCostCall.getReturnData(),
					"校验接口返回");

			Thread.sleep(20000);

			verifyDd(adRateInfoPoList, costAmount);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SettleAdCost_014() {
		Logger.start(true, "买手(广告费用余额+广告费奖金余额+用户余额)>广告费用,"
				+ "广告费用余额和广告费奖金余额都为0，商品广告费用结算成功");
		try {

			List<AdRateInfoPo> adRateInfoPoList = SettlementService
					.generateAdRateInfo(sellerId, true);

			//所有广告商品 总的需要结算的费用
			BigDecimal costAmount = adRateInfoPoList.stream()
					.map(ad -> ad.getCostAmount())
					.reduce(BigDecimal.ZERO, BigDecimal::add);

			//重置广告费用账户 
			SettlementService.resetBuyerAdvertisingFeeAccount(sellerId,
					BigDecimal.ZERO);

			//重置广告奖金账户 
			SettlementService
					.resetBuyerRewardAccount(sellerId, BigDecimal.ZERO);

			//重置广告奖金账户 
			SettlementService.resetRmbAccount(sellerId,
					costAmount.add(BigDecimal.TEN));

			Ts_CheckAdCost.callCheckAdCost();

			long orderId = adRateInfoPoList.get(0).getOrderId();

			mapAccount = SettlementService.getAccountByUserId(sellerId);

			settleAdCostReq.setOrderId(orderId);

			settleAdCostCall.setData(settleAdCostReq);

			settleAdCostCall.callService();

			Logger.verifyEquals("ok", settleAdCostCall.getReturnData(),
					"校验接口返回");
			Thread.sleep(20000);
			verifyDd(adRateInfoPoList, costAmount);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SettleAdCost_015() {
		Logger.start(true, "买手广告结算成功后,修改结算状态为0,重复结算");
		try {

			List<AdRateInfoPo> adRateInfoPoList = SettlementService
					.generateAdRateInfo(sellerId, true);

			//所有广告商品 总的需要结算的费用
			BigDecimal costAmount = adRateInfoPoList.stream()
					.map(ad -> ad.getCostAmount())
					.reduce(BigDecimal.ZERO, BigDecimal::add);

			//重置广告费用账户 
			SettlementService.resetBuyerAdvertisingFeeAccount(sellerId,
					new BigDecimal(100));

			//重置广告奖金账户 
			SettlementService.resetBuyerRewardAccount(sellerId, new BigDecimal(
					100));

			/*			//重置广告奖金账户 
						SettlementService.resetRmbAccount(sellerId,
								costAmount.add(BigDecimal.TEN));*/

			Ts_CheckAdCost.callCheckAdCost();

			long orderId = adRateInfoPoList.get(0).getOrderId();

			mapAccount = SettlementService.getAccountByUserId(sellerId);

			settleAdCostReq.setOrderId(orderId);

			settleAdCostCall.setData(settleAdCostReq);

			settleAdCostCall.callService();

			Logger.verifyEquals("ok", settleAdCostCall.getReturnData(),
					"校验接口返回");

			Thread.sleep(20000);

			//广告费结算表
			YmtSettlementInvoice ymtSettlementInvoice = ymtSettlementInvoiceWapper
					.selectYmtSettlementInvoice(String.valueOf(orderId)).get(0);

			String invoiceId = ymtSettlementInvoice.getInvoiceId();

			//修改结算状态为初始为结算状态
			new DefaultWapper()
					.executeUpdateSql(String
							.format("update Ymt_SettlementInvoice set SettlementStatus=0 where InvoiceId='%s'",
									invoiceId));

			new DefaultWapper()
					.executeUpdateSql(String
							.format("update Ymt_SettlementDetail set Status=0 where InvoiceId='%s'",
									invoiceId));

			settleAdCostCall.callService();

			Thread.sleep(20000);

			verifyDd(adRateInfoPoList, costAmount);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SettleAdCost_016() {
		Logger.start(true, "广告费用，广告奖金账户结算成功后，修改广告费用，广告奖金账户余额为0"
				+ "修改Ymt_SettlementInvoice,"
				+ "Ymt_SettlementDetail 结算状态为0，重新结算");
		try {

			List<AdRateInfoPo> adRateInfoPoList = SettlementService
					.generateAdRateInfo(sellerId, true);

			//所有广告商品 总的需要结算的费用
			BigDecimal costAmount = adRateInfoPoList.stream()
					.map(ad -> ad.getCostAmount())
					.reduce(BigDecimal.ZERO, BigDecimal::add);

			//重置广告费用账户 
			SettlementService.resetBuyerAdvertisingFeeAccount(sellerId,
					new BigDecimal(100));

			//重置广告奖金账户 
			SettlementService.resetBuyerRewardAccount(sellerId, new BigDecimal(
					100));

			/*			//重置广告奖金账户 
						SettlementService.resetRmbAccount(sellerId,
								costAmount.add(BigDecimal.TEN));*/

			Ts_CheckAdCost.callCheckAdCost();

			long orderId = adRateInfoPoList.get(0).getOrderId();

			mapAccount = SettlementService.getAccountByUserId(sellerId);

			settleAdCostReq.setOrderId(orderId);

			settleAdCostCall.setData(settleAdCostReq);

			settleAdCostCall.callService();

			Logger.verifyEquals("ok", settleAdCostCall.getReturnData(),
					"校验接口返回");

			Thread.sleep(50000);

			//广告费结算表
			YmtSettlementInvoice ymtSettlementInvoice = new YmtSettlementInvoiceWapper()
					.selectYmtSettlementInvoice(String.valueOf(orderId)).get(0);

			String invoiceId = ymtSettlementInvoice.getInvoiceId();

			//修改结算状态为初始为结算状态
			new DefaultWapper()
					.executeUpdateSql(String
							.format("update Ymt_SettlementInvoice set SettlementStatus=0 where InvoiceId='%s'",
									invoiceId));

			new DefaultWapper()
					.executeUpdateSql(String
							.format("update Ymt_SettlementDetail set Status=0 where InvoiceId='%s'",
									invoiceId));
			//重置广告费用账户  0
			SettlementService.resetBuyerAdvertisingFeeAccount(sellerId,
					BigDecimal.ZERO);

			//重置广告奖金账户  0
			SettlementService
					.resetBuyerRewardAccount(sellerId, BigDecimal.ZERO);

			settleAdCostCall.callService();

			Thread.sleep(20000);

			verifyDd(adRateInfoPoList, costAmount);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({P1.class})
	@TestCase
	public void Tc_SettleAdCost_017() {
		Logger.start(true, "一个订单多个广告商品,其中一个商品24小时内有订单支付后取消记录");
		try {

			PlaceOrderResp placeOrderResp = SettlementService
					.placeOrder(sellerId);

			Order order = placeOrderResp.getOrderList().get(0);

			int sellerId = order.getSellerId();

			int orderId = order.getOrderId();
			int userId = placeOrderResp.getUserId();
			int traidngId = placeOrderResp.getTradingId();
			BigDecimal payAmount = placeOrderResp.getPayAmount();

			new OrderCallService()
					.orderPayRequest(userId, payAmount, traidngId);

			new OrderCallService().cancelOrder(orderId, userId,
					CancelOrderTypeEnum.BuyerCancelOrder);

			callGenerateAdRateInfo(orderId, order.getOrderInfoList());

			List<String> proIds = Arrays.asList(order.getOrderInfoList().get(0)
					.getProductId());

			List<String> proList = new ArrayList<String>();

			order.getOrderInfoList().forEach(
					item -> proList.add(item.getProductId()));

			settleAdCostReq.setOrderId(orderId);

			settleAdCostCall.setData(settleAdCostReq);

			settleAdCostCall.callService();

			Logger.verifyEquals("ok", settleAdCostCall.getReturnData(),
					"校验接口返回");

			verifyDb2(userId, sellerId, orderId, proList);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
}
